【设计模式】创建型模式之简单工厂模式
1.模式介绍
-
简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
-
现实生活中,工厂是负责生产产品的;同样在设计模式中,简单工厂模式我们可以理解为负责生产对象的一个类,称为“工厂类”。
2.解决的问题
将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。
3.实际案例
需求:实现一个计算器,包含最基本的加减乘除操作。
需求分析:
首先,加减乘除属于某种操作,因此可以定义一个所有操作的超类Operation类。
其有一个抽象方法getResult(),需要子类进行实现,具体内部实现策略由具体子类提供。
而OperationFactory根据+、-、*、/操作的不同来生成具体的Operation子类。
public abstract class Operation { protected double numA; protected double numB; public double getNumA() { return numA; } public void setNumA(double numA) { this.numA = numA; } public double getNumB() { return numB; } public void setNumB(double numB) { this.numB = numB; } protected abstract double getResult(double numA, double numB); }
OperationAdd类继承Operation类,表示加法操作。
public class OperationAdd extends Operation { @Override protected double getResult(double numA, double numB) { return numA + numB; } }
同理,OperationMinus、OperationMultiply、OperationDivide分别表示减法、乘法、除法操作。
public class OperationMinus extends Operation { @Override protected double getResult(double numA, double numB) { return numA - numB; } }
public class OperationMultiply extends Operation{ @Override protected double getResult(double numA, double numB) { return numA * numB; } }
public class OperationDivide extends Operation { @Override protected double getResult(double numA, double numB) { if (Double.compare(numB, 0) == 0) { throw new IllegalArgumentException("numB can not be zero!"); } return numA / numB; } }
OperationFactory是一个Operation工厂,根据具体传入的操作符来返回对应的具体Operation子类。
public class OperationFactory { public static Operation getOperation(String oper) { switch (oper) { case "+": return new OperationAdd(); case "-": return new OperationMinus(); case "*": return new OperationMultiply(); case "/": return new OperationDivide(); default: return null; } } }
如下,根据实际传入的operation操作符的不同,执行不同的运算。
public class Main { public static void main(String[] args) { double numA = 8000; double numB = 1000; /** * 根据提供的operation的不同,执行不同的运算 */ String oper = "+"; double result; Operation operation; operation = OperationFactory.getOperation(oper); result = operation.getResult(numA, numB); System.out.println(result); oper = "-"; operation = OperationFactory.getOperation(oper); result = operation.getResult(numA, numB); System.out.println(result); oper = "*"; operation = OperationFactory.getOperation(oper); result = operation.getResult(numA, numB); System.out.println(result); oper = "/"; operation = OperationFactory.getOperation(oper); result = operation.getResult(numA, numB); System.out.println(result); } } /** * 运行结果 * 9000.0 7000.0 8000000.0 8.0 */
4.优点
-
将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;
-
把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。
5.缺点
-
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
-
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
-
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
6.应用场景
在了解了优缺点后,我们知道了简单工厂模式的应用场景:
-
客户如果只知道传入工厂类的参数,对于如何创建对象的逻辑不关心时;
-
当工厂类负责创建的对象(具体产品)比较少时。